/*
 * G2OResolve.cpp
 *
 *  Created on: Sep 11, 2016
 *      Author: ubuntu
 */

#include <unistd.h>
#include "G2OResolve.h"
#include "G2OStatus.h"

#include "../common.h"
#include "../Conf.h"

G2OResolve::G2OResolve()
{
	m_bTerminated = false;
	m_pDBPool = getConf()->cpool;
	pthread_mutex_init(&m_summa_mutex, NULL);
}

G2OResolve::~G2OResolve()
{
	pthread_mutex_destroy(&m_summa_mutex);
}

void G2OResolve::init()
{
	Connection *pConn = m_pDBPool->grab();
	if (!pConn)
		return;
	Query query = pConn->query();
reinit:
	try {
		time_t starttime, stoptime, lasttime;
		double lng_end, lat_end;
		int version;
		query << "select obdid,starttime,stoptime,lasttime,lng_end,lat_end,version from zb_g2o_allobd where type=1";
		StoreQueryResult res = query.store();
		for (size_t i = 0; i < res.num_rows(); i++) {
			starttime = strtoul(res[i][1].c_str(), NULL, 10);
			stoptime = strtoul(res[i][2].c_str(), NULL, 10);
			lasttime = strtoul(res[i][3].c_str(), NULL, 10);
			lng_end = strtod(res[i][4].c_str(), NULL);
			lat_end = strtod(res[i][5].c_str(), NULL);
			version = strtoul(res[i][6].c_str(), NULL, 10);
			G2OStatus *pStatus = new G2OStatus(res[i][0].c_str());
			pStatus->init(1, starttime, stoptime, lng_end, lat_end, lasttime, version);
			saveStatus(pStatus);
		}
	} catch (mysqlpp::BadQuery &er) {
		if (er.errnum() == 1146) {
			createAllDB(pConn);
			goto reinit;
		}
		debug(LOG_DEBUG, "Query error: %s", er.what());
		exit(1);
	}
	m_pDBPool->release(pConn);
}

void G2OResolve::push(G2OSummary *pSummary)
{
	pthread_mutex_lock(&m_summa_mutex);
	m_lstSummary.push(pSummary);
	pthread_mutex_unlock(&m_summa_mutex);
}

void G2OResolve::stop()
{
	m_bTerminated = true;
}

void G2OResolve::run()
{
	if (m_pDBPool == NULL) {
		debug(LOG_DEBUG, "数据库线程池错误");
		stop();
	}
	while (!m_bTerminated) {
		if (m_lstSummary.empty()) {
			usleep(1000);
			continue;
		}

		G2OSummary *pSummary = NULL;
		pthread_mutex_lock(&m_summa_mutex);
		if (!m_lstSummary.empty()) {
			pSummary = m_lstSummary.front();
			m_lstSummary.pop();
		}
		pthread_mutex_unlock(&m_summa_mutex);
		if (pSummary) {
			pSummary->parse();
//			pSummary->debugInfo();
			writeDB(pSummary);
			delete pSummary;
		}
	}
}

void G2OResolve::saveStatus(G2OStatus *pStatus)
{
	int hs = hash(pStatus->getObdid());
	m_arrStatus[hs].push_back(pStatus);
}

int G2OResolve::hash(const char *s)
{
	return 1;
}

void G2OResolve::writeDB(G2OSummary *pSummary)
{
	Connection *pConn = m_pDBPool->grab();
	if (pConn) {
rewrite:
		try {
			pSummary->writeDB(pConn);
		} catch (mysqlpp::BadQuery &er) {
			if (er.errnum() == 1146) {
				pSummary->createTB(pConn);
				goto rewrite;
			}
			debug(LOG_ERR, "Query error: %s", er.what());
		}
		m_pDBPool->release(pConn);
	}
}

void G2OResolve::getBuf(unsigned char *buf, size_t len)
{
	G2OSummary *pSummary = new G2OSummary();
	pSummary->getBuf(buf, len);
	push(pSummary);
}

void G2OResolve::createAllDB(Connection *pConn)
{
	Query query = pConn->query();
	query << "CREATE TABLE IF NOT EXISTS zb_g2o_allobd" <<
		"(obdid char(14) NOT NULL COMMENT '主键OBD序列号', type int unsigned NOT NULL DEFAULT '1' COMMENT '设备类型', " <<
		"starttime int unsigned NOT NULL DEFAULT '0' COMMENT '起始时间', stoptime int unsigned NOT NULL DEFAULT '0' COMMENT '最后时间', " <<
		"lasttime int unsigned NOT NULL DEFAULT '0' COMMENT '最后位置时间', " << 
		"version int unsigned NOT  NULL DEFAULT '0' COMMENT '元征OBD二代软件版本号', " <<
		"lng_end float(10,6) unsigned NOT NULL DEFAULT '0' COMMENT '经度', lat_end float(10, 6) unsigned NOT NULL DEFAULT '0' COMMENT '纬度', " <<
		"updateable int unsigned NOT NULL DEFAULT '1' COMMENT '是否可升级', " <<
		"req_res int unsigned NOT NULL DEFAULT '1' COMMENT '登录请求结果[0: 失败, 1:成功, 2: 超负荷, 3:错误重指', " <<
		"beat_cyc int unsigned NOT NULL DEFAULT '3' COMMENT '心跳周期', " <<
		"gpssam_cyc int unsigned NOT NULL DEFAULT '1' COMMENT 'GPS采样周期', gpstrs_cyc int unsigned NOT NULL DEFAULT '4' COMMENT 'GPS传输周期', " <<
		"datasam_cyc int unsigned NOT NULL DEFAULT '15' COMMENT '数据采样周期', datatrs_cyc int unsigned NOT NULL DEFAULT '30' COMMENT '数据传输周期', " <<
		"data_rsp int unsigned NOT NULL DEFAULT '1' COMMENT '是否应答', " <<

		"primary key (obdid)) ENGINE=InnoDB DEFAULT CHARSET=utf8";
	query.exec();
}
